package com.vc.opengl;

import java.lang.ref.WeakReference;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;

/**
 * 实际的绘图动作
 * @author Administrator
 *
 */
public class GLRender implements GLSurfaceView.Renderer{
	
	  static String TAG = "GLRender";
	  
	  private static boolean soloaded = false;
	  
	  private WeakReference<GLView> m_view;
	  private WeakReference<GLRenderListener> mlistener;
	  private EventHandler mEventHandler;
	  
	  private int mUIWidth = 0;
	  private int mUIHeight = 0;

	  public float mBrightness = 1.2F;
	  public float mContrast = 1.93F;
	  public float mSaturation = 1.05F;

	  boolean mfLandscape = false;
	  boolean mfClip = false;
	  boolean mSetMode = false;	  
	  private int mRotation = 0;
	  
	  private int mNativeContext = 0;
	  
	  boolean mfInited = false;

	  public static int MSG_RENDER = 0;
	  public static int MSG_FLUSH = 1;
	  public static int MSG_RESET = 2;
	  public static int MSG_SHOW_GLVIEW = 3;

	  public static int getGLVersion(Context context)
	  {
	    ActivityManager am = (ActivityManager)context.getSystemService("activity");
	    ConfigurationInfo info = am.getDeviceConfigurationInfo();
	    return info.reqGlEsVersion >= 131072 ? 2 : 1;
	  }

	  public GLRender(GLView view, GLRenderListener listener)
	  {
	    if (!soloaded) {
	      System.loadLibrary("VideoController");
	      soloaded = true;
	    }

	    this.m_view = new WeakReference<GLView>(view);
	    this.mlistener = new WeakReference<GLRenderListener>(listener);
	    
	    Looper looper;
	    if ((looper = Looper.myLooper()) != null)
	      this.mEventHandler = new EventHandler(this, looper);
	    else if ((looper = Looper.getMainLooper()) != null)
	      this.mEventHandler = new EventHandler(this, looper);
	    else {
	      this.mEventHandler = null;
	    }
	  }

	  public void onDrawFrame(GL10 gl) {
	    if (this.m_view.get() == null) {
	      return;
	    }
	    Log.d(TAG, "onDrawFrame");
	    render();
	  }

	  public void onSurfaceChanged(GL10 gl, int width, int height) {
		  Log.d(TAG, "onSurfaceChanged|width="+width+",height="+height);
		  if ((this.mUIWidth != width) || (this.mUIHeight != height)) {
		      gl.glViewport(0, 0, width, height);
		      this.mUIWidth = width;
		      this.mUIHeight = height;
		      Log.d(TAG, "onSurfaceChanged|glViewport,width="+width+",height="+height);
		  }
	  }

	  public void onSurfaceCreated(GL10 gl, EGLConfig config){
		  Log.d(TAG, "onSurfaceCreated");		   
	  }

	  public void surfaceCreated(SurfaceHolder holder) {
	    Log.d(TAG, "surfaceCreated");
	    init(getGLVersion(this.m_view.get().getContext()), new WeakReference<GLRender>(this));
	    this.mfInited = true;
	    setParam(this.mBrightness, this.mContrast, this.mSaturation);
	    setRotation(this.mRotation);
	    if (this.mlistener.get() != null){
	      this.mlistener.get().onRenderCreated(this);
	    }
	  }

	  public void onSurfaceDestroyed()
	  {
	    Log.d(TAG, "onSurfaceDestroyed");
	    if (this.mlistener.get() != null) {
	      this.mlistener.get().onRenderDestroyed(this);
	    }
	    Uninit();
	    this.mfInited = false;
	    this.mNativeContext = 0;
	    this.mUIWidth = 0;
	    this.mUIHeight = 0;
	  }

	  private static void onNativeTest(String msg){
		  Log.d(TAG, "onNativeTest,msg="+msg);
	  }

	  /**
	   * 由底层回调该方法，该方法才会去通知该GLRender对象去做render()动作，不回调的话，不去做render()，性能的考虑
	   * @param render_ref
	   * @param msg
	   * @param extrainfo
	   */
	  private static void onNativeNotify(Object render_ref, int msg, Object extrainfo)
	  {
		  Log.d(TAG, "onNativeNotify,msg="+msg);
		  WeakReference<GLRender> wp = (WeakReference<GLRender>)render_ref;
		  if (wp.get() != null){
			  if (msg == MSG_RENDER) {
				  wp.get().notifyupdateui();
			  }
		  }
	  }


	  private void notifyupdateui()
	  {
		Log.d(TAG, "notifyupdateui");
	    if (this.mEventHandler != null) {
	      Message m = this.mEventHandler.obtainMessage(0, 0, 0, Integer.valueOf(0));
	      this.mEventHandler.sendMessage(m);
	    } else {
	      Log.e(TAG, "notifyupdateui|mEventHandler is null");
	    }
	  }

	  public void requestRender()
	  {
		Log.d(TAG, "requestRender");
	    if(!this.mSetMode){
	        setDisplayMode(((GLView)this.m_view.get()).getWidth(), ((GLView)this.m_view.get()).getHeight(), this.mfLandscape, this.mfClip);
	        this.mSetMode = true;
	    }
	    
	    if (this.m_view.get() != null){
	      this.m_view.get().onRequestRender();
	    }else{
	      Log.e(TAG, "requestRender Err!");
	    }
	  }
	  
	  /**
	   * native函数定义
	   * @param paramInt 
	   * @param paramObject 渲染器对象
	   */
	  private native void init(int glVersion, WeakReference<GLRender> glRender);

	  
	  /**
	   * 渲染动作
	   */
	  private native void render();

	  /**
	   * 暂停视频，例如切换出去了，或者切换到语音了
	   */
	  public native void onPause();

	  /**
	   * 暂停后继续
	   */
	  public native void onResume();
	  
	  /**
	   * 设置视频参数
	   * @param mBrightness 亮度
	   * @param mContrast 对比度
	   * @param mSaturation 饱和度
	   */
	  private native void setParam(float mBrightness, float mContrast, float mSaturation);

	  /**
	   * 卸载，通知底层做内存回收
	   */
	  private native void Uninit();

	  /**
	   * 刷新？
	   * @param paramBoolean
	   */
	  private native void flush(boolean paramBoolean);

	  /**
	   * 设置旋转角度
	   * @param paramInt
	   */
	  private native void setRotation(int rotation);

	  /**
	   * 获取当前角度
	   * @return
	   */
	  private native int getRotation();

	  /**
	   * 设置显示模式
	   * @param width 宽度
	   * @param height 高度
	   * @param mfLandscape 横着还是竖着
	   * @param mfClip
	   */
	  private native void setDisplayMode(int width, int height, boolean mfLandscape, boolean mfClip);

	  
	  public void setGlRotation(int rotation) {
	    this.mRotation = rotation;
	    if (this.mfInited)
	      setRotation(rotation);
	  }

	  public int getGlRotation()
	  {
	    return this.mRotation;
	  }
		  
	  /**
	   * 事件handler，由JNI后端来调用，当后端接收到帧数据时，会通过此类来发送render通知（手动render，比自动render性能优越）
	   * @author Administrator
	   *
	   */
	  private static class EventHandler extends Handler
	  {
	    private WeakReference<GLRender> mGlRender;
		//private GLRender mGlRender;

	    public EventHandler(GLRender glRender, Looper looper)
	    {
	      super();
	      this.mGlRender = new WeakReference<GLRender>(glRender);
	      //this.mGlRender = glRender;
	    }

	    public void handleMessage(Message msg)
	    {
	    	GLRender glRender = this.mGlRender.get();
	    	if (glRender != null){
	    		glRender.requestRender();
	        }
//	    	mGlRender.requestRender();
	    }
	  }

	  /**
	   * 监听器
	   * @author Administrator
	   *
	   */
	  public static abstract interface GLRenderListener
	  {
	    public abstract void onRenderCreated(GLRender paramQQGlRender);

	    public abstract void onRenderDestroyed(GLRender paramQQGlRender);

	    public abstract void onRenderInfoNotify(GLRender paramQQGlRender, int width, int height, int angle);
	  }
	}